package ch.hoth.java.joocal;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

import com.google.gdata.data.DateTime;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.extensions.EventEntry;
import com.google.gdata.data.extensions.When;

public class CalendarController extends Observable{
	
	public static final String FILE_NAME = "out.xml";
	
	private List<Calendar> calendars;
	private List<Observer> observers;
	private Date selectedDate;
	
	public CalendarController(){
		calendars = new ArrayList<Calendar>();
		observers = new ArrayList<Observer>();
		selectedDate = new Date();
		//initialize();
	}
	
	public void setSelectedDate(Date selectedDate){
		this.selectedDate = selectedDate;
		notifyObservers(selectedDate);
	}
	public Date getSelectedDate(){
		return selectedDate;
	}
	
	public void addCalendar(Calendar calendar){
		calendars.add(calendar);
	}
	
	public void removeCalendar(Calendar calendar){
		calendars.remove(calendar);
	}
	
	public List<Calendar> getCalendars(){
		return calendars;
	}
	
	private void initialize(){
		// load prefs
		// load from xml
		load();
	}
	
	public void addObserver(Observer observer){
		observers.add(observer);
	}
	
	public void removeObserver(Observer observer){
		observers.remove(observer);
	}
	
	public void notifyObservers(Object obj){
		for (Observer o :observers){
			o.update(this, obj);
		}
	}
	
	public void load(){
		// from prefs, load files
		// for each files, create 1 calendar and add events to
		
		// check if dirty flag is set => be sure it is what you want to do : cancel your modifications
		// find xml file with $user.getCalendarName().xml
		// read dom and create Event
		// put event in events list
		// update listeners
		
		 try {
			 
			 List<Event2> events = calendars.get(0).getEvents();
			 events.clear();
			 
			 SAXBuilder builder = new SAXBuilder();
			 //builder.setFeature("", true);
			 //builder.setValidation(true);
			 builder.setIgnoringElementContentWhitespace(true);
			 Document doc = builder.build(new File(FILE_NAME));
			 
			 List list = doc.getContent();
			 
			 for (int i=0; i< ((Element) doc.getContent().get(0)).getChildren().size(); i++){
				 
				 EventEntry entry = new EventEntry();
				 Event2 event2 = new Event2(entry);
				 
				 Element e = (Element) ((Element) doc.getContent().get(0)).getChildren().get(i);
				 List<Attribute> attr = e.getAttributes();
				 for (Attribute a:attr){
					 event2.setStatus(Status.NEW);
				 }
				 Element gEvent = e.getChild("gEntry");
				 attr = gEvent.getAttributes();
				 entry.setTitle(new PlainTextConstruct(attr.get(0).getValue()));
				 When when = new When();
				 when.setStartTime(new DateTime(attr.get(1).getLongValue()));
				 when.setEndTime(new DateTime(attr.get(2).getLongValue()));
				 entry.addTime(when);
				 
				 events.add(event2);
				 
			 }
			 //replace by TODAY date here. For dev purpose, use a long value saved in xml
			 notifyObservers(new Date(new DateTime(1145278800000l).getValue()));
			 
		 }
         catch (Exception e) {
			e.printStackTrace();
		}


	}
	
	public boolean saveCalendar(Calendar calendar){
		
	/*	Calendar cal = new Calendar(GoogleUserFactory.getUser("dagomox"));
		EventEntry ge1 = GEventsFactory.getEvent();
		EventEntry ge2 = GEventsFactory.getEvent();
		EventEntry ge3 = GEventsFactory.getEvent();
		EventEntry ge4 = GEventsFactory.getEvent();
		
		Event2 e1 = new Event2(ge1);
		Event2 e2 = new Event2(ge2);
		Event2 e3 = new Event2(ge3);
		Event2 e4 = new Event2(ge4);
		
		cal.addEvent(e1);
		cal.addEvent(e2);
		cal.addEvent(e3);
		cal.addEvent(e4);
		
		*/
		
		Calendar cal = calendars.get(0);
		
		try{
		    FileOutputStream os = new FileOutputStream(new File(FILE_NAME));
			 
			 Document docu = new Document();
			 Element root = new Element("calendar");
			 
			 for (Event2 e :cal.getEvents()){
			 
				 Element event = new Element("event");
				 event.setAttribute("status", e.getStatus());
				 Element gEvent = new Element("gEntry");
				 
				 gEvent.setAttribute("title", e.getGEntry().getTitle().getPlainText());
				 gEvent.setAttribute("startdate", "" + e.getGEntry().getTimes().get(0).getStartTime().getValue());
				 gEvent.setAttribute("enddate", "" + e.getGEntry().getTimes().get(0).getEndTime().getValue());
				 String uri = ""; 
				 if (e.getGEntry().getSelfLink() != null){
					 uri = e.getGEntry().getSelfLink().getHref();
					 
				 }
				 gEvent.setAttribute("uri", uri);
				 
				 event.addContent(gEvent);
				 root.addContent(event);
			 }
			 
			 docu.addContent(root);
			 
			 
			 
			XMLOutputter output = new XMLOutputter();
			Format f = Format.getPrettyFormat();
			f.setIndent("    ");
			f.setLineSeparator("\n");
			output.setFormat(f);
			output.output(docu, os);
			
		}
		catch (Exception e){
			
		}
	   
		return true;
	}
	
	private boolean publish(Calendar calendar){
		// find each unpublished nodes
		// connect to google
		// publish each events.
		// update events with new google content (take new published events)
		// update listeners
		// set need publish to false
		return true;
	}
	
	public boolean update(Calendar calender){
		
		// !!! you will lose your modifications unpublished !!!
		
		// backup events
		// connect to server
		// get all futur events
		// put event in events list
		// set dirty flag to true
		// set need publish to false
		// update listeners
		
		return true;
	}
	
	public void publishAll(){
		for (Calendar calendar :calendars){
			boolean ok = publish(calendar);
			if (!ok){
				// log problem
			}
		}
	}
	
	public void updateAll(){
		for (Calendar calendar :calendars){
			boolean ok = update(calendar);
			if (!ok){
				// log problem
			}
		}
	}
}
